package com.example.friendfindertwo;

import java.util.HashMap;
import java.util.List;

import model.Event;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ActionBar;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.SearchView;
import android.widget.Switch;
import android.widget.Toast;

import com.example.friendfindertwo.application.StartApplication;
import com.example.friendfindertwo.broadcastReceiver.FriendLocationReceiver;
import com.example.friendfindertwo.receiverInterface.IFriendLocationReceiver;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.parse.ParseInstallation;
import com.parse.ParsePush;
import com.parse.PushService;


public class SecondMap extends Activity implements OnMapClickListener, OnMapLongClickListener, OnCameraChangeListener, ConnectionCallbacks, OnConnectionFailedListener, IFriendLocationReceiver {
	private LatLng currentPosition;
	private GoogleMap map;
	private Marker currentMarker;
	private HashMap <Marker, Event> markerList = new HashMap<Marker, Event>();
	private String account;
	private LocationManager locationManager;
	private List<Event> mEventList;
	private Marker eventMarker;
	private HashMap<String, String> markerEventHashMap;
	
	private final LocationListener gpsLocationListener = new LocationListener(){
		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onLocationChanged(Location location) {
			locationManager.removeUpdates(networkLocationListener);
			try {
				Log.d("sendPushNotification", "sendPushNotification");
				if(currentPosition != null){
                	LoginActivity.dataBaseObject.updateLocationDatabase(currentPosition);
                }
				sendPushNotification();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} ;
		}
	};

	private final LocationListener networkLocationListener =
			new LocationListener(){

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras){
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onLocationChanged(Location location) {
			try {
				Log.d("sendPushNotification", "sendPushNotification");
				//update location on database
	    	    if(currentPosition != null){
                	LoginActivity.dataBaseObject.updateLocationDatabase(currentPosition);
                }
				sendPushNotification();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} ;

		}
	};

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		markerEventHashMap = new HashMap<String, String>();
		
		account = ParseDatabase.getAccountName();

		FriendLocationReceiver.registerAsListener(this);

		locationManager = (LocationManager) 
				getSystemService(Context.LOCATION_SERVICE);

		// Set up the Push Notification
		PushService.setDefaultPushCallback(this, SecondMap.class);
		// Save the current Installation to Parse.    
		ParseInstallation.getCurrentInstallation().saveInBackground();
		subscribeToPushNotification();

		Log.i("MYMAP", "befor onCreate");
		if (isPlayServicesAvailable()) {
			setContentView(R.layout.activity_second_map);
			Log.i("MYMAP", "onCreate");

			if(((MapFragment) getFragmentManager().findFragmentById(R.id.map)) != null){
				map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
				
				map.setOnInfoWindowClickListener(new OnInfoWindowClickListener(){

					@Override
					public void onInfoWindowClick(Marker marker) {
						// TODO Auto-generated method stub
						Toast.makeText(getApplicationContext(), "huhuuu", Toast.LENGTH_SHORT).show();
						
					}
					
				});
			}
		}

		// Set the position button for Google Maps UI
		map.setMyLocationEnabled(true);
		setUpMap();

		//Btn create event (kind of listenner method) 
//		findViewById(R.id.btn_createEvent).setOnClickListener(mGlobal_OnClickListener);
//		findViewById(R.id.btn_findFriend).setOnClickListener(mGlobal_OnClickListener);

		// get action bar   
		ActionBar actionBar = getActionBar();

		// Enabling Up / Back navigation
		actionBar.setDisplayHomeAsUpEnabled(false);
		actionBar.setSubtitle(R.string.title_activity_second_map);

		Switch toggle = (Switch) findViewById(R.id.onlineSwitch);
		toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				if (isChecked) {
					LoginActivity.dataBaseObject.setOnline();
				} else {
					LoginActivity.dataBaseObject.setOffline();
				}
			}
		});

		//new DisplayFriends().execute();
		//displayEventMarker();
		//new DisplayEvents().execute();
	}//end of function OnCreate

	@Override
	protected void onResume() {
		super.onResume();
		locationManager.requestLocationUpdates(
				LocationManager.NETWORK_PROVIDER, 5000, 1,
				networkLocationListener);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
				5000, 1, gpsLocationListener);

		// check if GPS enabled
	    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
	    	Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
	    	if(currentPosition != null) {
				currentPosition = new LatLng(location.getLatitude(),location.getLongitude());
			}
	    } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
	    	Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
	    	if(currentPosition != null) {
				currentPosition = new LatLng(location.getLatitude(),location.getLongitude());
			}
	    } else {
	    	currentPosition = new LatLng(0,0);
	    }

		
		new DisplayEvents().execute();
		new DisplayEvents().execute();

	}

	@Override
	protected void onPause() {
		super.onPause();
		locationManager.removeUpdates(networkLocationListener);
		locationManager.removeUpdates(gpsLocationListener);
	}

	//Global On click listener for all views
//	final OnClickListener mGlobal_OnClickListener = new OnClickListener() {
//		public void onClick(final View v) {
//			switch(v.getId()) {
//			case R.id.btn_createEvent:
//				//Inform the user the button1 has been clicked
//				System.out.println("My position : " + currentPosition);
//				// Toast.makeText(getApplicationContext(), "Button1 clicked.", Toast.LENGTH_SHORT).show();
//				Intent intent = new Intent(getApplicationContext(), CreateEventActivity.class);
//				intent.putExtra("currentPosition", true);
//				if (currentPosition == null){
//					Log.i("second map", "null");
//				}
//				else Log.i("coordinates", currentPosition.toString());
//
//				intent.putExtra("current latitude", currentPosition.latitude);
//				intent.putExtra("current longitude", currentPosition.longitude);
//				startActivity(intent);
//				break;
//			case R.id.btn_findFriend: // TODO
//				//Inform the user the button2 has been clicked
//
//				Intent friendintent = new Intent(getApplicationContext(), FriendManagerActivity.class);
//				startActivity(friendintent);
//				break;
//			}
//		}
//	};

	public void moveCamera()
	{
		// Move the camera instantly to current position with a zoom of 15.
		map.moveCamera(CameraUpdateFactory.newLatLngZoom(currentPosition, 15));
		// Zoom in, animating the camera.
		map.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);	    
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main_actions, menu);
		// Associate searchable configuration with the SearchView
		SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
		SearchView searchView = (SearchView) menu.findItem(R.id.action_search)
				.getActionView();
		searchView.setSearchableInfo(searchManager
				.getSearchableInfo(getComponentName())); 

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		switch(id){
		case R.id.event_list:
			Log.i("SecondMap", "event list");
			Intent intent = new Intent(getApplicationContext(), EventListActivity.class);
			startActivity(intent);
			break;
		case R.id.friend_manager:
			Log.i("SecondMap", "friend manager");
			Intent friendintent = new Intent(getApplicationContext(), FriendManagerActivity.class);
			startActivity(friendintent);
			break;
		default:
			super.onOptionsItemSelected(item);
		}
		if (id == R.id.action_settings) {
			return true;
		}
		else if(id == R.id.action_logout){
			if (LoginActivity.mPlusClient.isConnected()) {
				//LoginActivity.clearDefaultAccount();
				//LoginActivity.disconnect();
				//onDisconnected();
			}
		}

		return true;
	}

	protected boolean isPlayServicesAvailable() {
		int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

		if (status == ConnectionResult.SUCCESS) {
			return (true);
		} else if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
			// deal with error
		} else {
			// maps is not available
		}
		return (false);
	}

	private void setUpMap() {
		map.setOnMapClickListener(this);
		map.setOnMapLongClickListener(this);
		map.setOnCameraChangeListener(this);
	}

	@Override
	public void onCameraChange(CameraPosition arg0) {
		// TODO Auto-generated method stub	
	}

	@Override
	public void onMapLongClick(LatLng point) {
		// TODO Auto-generated method stub	
		//MarkerOptions markerOptions = new MarkerOptions().title("test").position(point);
		//markerList.put(map.addMarker(markerOptions), new Event());

		Intent intent = new Intent(getApplicationContext(), CreateEventActivity.class);
		intent.putExtra("long click", true);
		intent.putExtra("latitude", point.latitude);
		intent.putExtra("longitude", point.longitude);
		startActivity(intent);
	}

	@Override
	public void onMapClick(LatLng point) {
		// TODO Auto-generated method stub	
	}

	@Override
	public void onConnectionFailed(ConnectionResult result) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onConnected(Bundle connectionHint) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onDisconnected() {
		// TODO Auto-generated method stub
	}

	private void subscribeToPushNotification() {
		// When users indicate they are Giants fans, we subscribe them to that channel.
		PushService.subscribe(getApplicationContext(), "userTable", SecondMap.class);
	}

	private void sendPushNotification() throws JSONException {
		ParsePush push = new ParsePush();
		push.setChannel("userTable");
		JSONObject data = new JSONObject("{\"action\": \"com.example.friendfindertwo.UPDATE_STATUS\"}\"");
		push.setData(data);
		push.sendInBackground();
	}
	
	private void displayEventMarker()
	{

		this.mEventList = StartApplication.getAllEvents();
		Log.i("SecondMap.onresume", "StartApplication.getAllEvents()tests");

		
		for(Event event : this.mEventList)
		{
			this.eventMarker = map.addMarker(new MarkerOptions()
	        .position(event.getPosition())
	        .title(event.getTitle())
	        .snippet(event.getDescription())
	        .visible(true)
	        .icon(BitmapDescriptorFactory
	        .defaultMarker(BitmapDescriptorFactory.HUE_BLUE))); //Blue marker
			
			markerEventHashMap.put(eventMarker.getId(), event.getObjectId());
		}
	}

	@Override
	public void onFriendLocationChanged() {
		// TODO Auto-generated method stub
		new DisplayFriends().execute();
	}

	private class DisplayFriends extends AsyncTask{
		String[] friends;

		@Override
		protected Object doInBackground(Object... arg0) {
			// TODO Auto-generated method stub
			//showFriends();
			friends = new String[LoginActivity.dataBaseObject.countDataBaseSize()];
			friends = LoginActivity.dataBaseObject.getFriendListOnline();
			return null;
		}

		@Override
		protected void onPostExecute(Object result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			Log.i("second map display friend", "execute");
			for (int i=0;i<friends.length;i++)
			{
				map.addMarker(new MarkerOptions()
				.title(friends[i])
				.position(LoginActivity.dataBaseObject.getLastLocation(friends[i]))
				.visible(true)
				.icon(BitmapDescriptorFactory
						.fromResource(R.drawable.ic_friend_icon))
						.snippet(LoginActivity.dataBaseObject.getLastUpdateTime(friends[i])));
			}
		}
	}
	
	private class DisplayEvents extends AsyncTask{

		@Override
		protected Object doInBackground(Object... arg0) {
			// TODO Auto-generated method stub
			mEventList = StartApplication.getAllEvents();
			Log.i("SecondMap.onresume", "StartApplication.getAllEvents()tests");
			return null;
		}
		
		@Override
		protected void onPostExecute(Object result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			Log.i("second map display event", "execute");
			for(Event event : mEventList)
			{
				eventMarker = map.addMarker(new MarkerOptions()
		        .position(event.getPosition())
		        .title(event.getTitle())
		        .snippet(event.getDescription())
		        .visible(true)
		        .icon(BitmapDescriptorFactory
		        .defaultMarker(BitmapDescriptorFactory.HUE_BLUE))); //Blue marker

			}
		}
		
	}
	
	
} // end of class
